#include "stdafx.h"
#include "cef_control_base.h"
#include "util/util.h"

namespace ui 
{
	void CefControlBase::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {}

	// Called when the browser is closing.
	void CefControlBase::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {}

	// Called when the browser has been closed.
	void CefControlBase::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {}

	// Set the window URL address.
	void CefControlBase::OnSetAddress(const std::string& url) {}

	// Set the window title.
	void CefControlBase::OnSetTitle(const std::string& title) {}

	// Set the Favicon image.
	void CefControlBase::OnSetFavicon(CefRefPtr<CefImage> image) {}

	// Set fullscreen mode.
	void CefControlBase::OnSetFullscreen(bool fullscreen) {}

	// Auto-resize contents.
	void CefControlBase::OnAutoResize(const CefSize& new_size) {}

	// Set the loading state.
	void CefControlBase::OnSetLoadingState(bool isLoading,
		bool canGoBack,
		bool canGoForward) {}

	// Set the draggable regions.
	void CefControlBase::OnSetDraggableRegions(
		const std::vector<CefDraggableRegion>& regions) {}

	// Set focus to the next/previous control.
	void CefControlBase::OnTakeFocus(bool next) {}

	bool CefControlBase::OnAfterCreated(CefRefPtr<CefBrowser> browser)
	{
		this->SetPos(this->GetPos());
		/*if (cb_after_created_)
			cb_after_created_(browser);*/
		return false;
	}

void CefControlBase::OnPaint(CefRefPtr<CefBrowser> browser, CefRenderHandler::PaintElementType type, const CefRenderHandler::RectList& dirtyRects, const std::string* buffer, int width, int height)
{
	return;
}

void CefControlBase::OnPopupShow(CefRefPtr<CefBrowser> browser, bool show)
{
	return;
}

void CefControlBase::OnPopupSize(CefRefPtr<CefBrowser> browser, const CefRect& rect)
{
	return;
}

void CefControlBase::UpdateWindowPos()
{
	this->SetPos(this->GetPos());
}

void CefControlBase::OnBeforeContextMenu(CefRefPtr<CefMenuModel> model)
{
	if (cb_before_menu_)
		cb_before_menu_(model);
}

bool CefControlBase::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, int command_id, CefContextMenuHandler::EventFlags event_flags)
{
	if (cb_menu_command_)
		return cb_menu_command_(browser, frame, params, command_id, event_flags);

	return false;
}

void CefControlBase::OnAddressChange(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& url)
{
	if (cb_url_change_)
		cb_url_change_(browser, frame, url);

	if (frame->IsMain())
	{
		auto old_url = url_;
		url_ = frame->GetURL();
		if (cb_main_url_change_ != nullptr && GetMainURL(old_url).compare(GetMainURL(url_)) != 0)
		{
			cb_main_url_change_(old_url, url_);
		}
	}
}

void CefControlBase::OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title)
{
	if (cb_title_change_)
		cb_title_change_(browser, title);
}

void CefControlBase::OnLoadingStateChange(CefRefPtr<CefBrowser> browser, bool isLoading, bool canGoBack, bool canGoForward)
{
	if (cb_loadstate_change_)
		cb_loadstate_change_(browser, isLoading, canGoBack, canGoForward);
}

void CefControlBase::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefLoadHandler::TransitionType transition_type)
{
	if (cb_load_start_)
		cb_load_start_(browser, frame, transition_type);
}

void CefControlBase::OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode)
{
	if (cb_load_end_)
		cb_load_end_(browser, frame, httpStatusCode);
}

void CefControlBase::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefLoadHandler::ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl)
{
	if (cb_load_error_)
		cb_load_error_(browser, frame, errorCode, errorText, failedUrl);
}
//
//bool CefControlBase::OnBeforePopup(CefRefPtr<CefBrowser> browser,
//	CefRefPtr<CefFrame> frame,
//	const CefString& target_url,
//	const CefString& target_frame_name,
//	CefLifeSpanHandler::WindowOpenDisposition target_disposition,
//	bool user_gesture,
//	const CefPopupFeatures& popupFeatures,
//	CefWindowInfo& windowInfo,
//	CefRefPtr<CefClient>& client,
//	CefBrowserSettings& settings,
//	bool* no_javascript_access)
//{
//	if (cb_link_click_ && !target_url.empty())
//		return cb_link_click_(target_url);
//
//	return false;
//}
//
//bool CefControlBase::OnAfterCreated(CefRefPtr<CefBrowser> browser)
//{
//	if (cb_after_created_)
//		cb_after_created_(browser);
//
//	return false;
//}
//
//void CefControlBase::OnBeforeClose(CefRefPtr<CefBrowser> browser)
//{
//	if (cb_before_close_)
//		cb_before_close_(browser);
//}
//
//bool CefControlBase::OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool is_redirect)
//{
//	bool result = false;
//
//	if (cb_before_browser_)
//		result = cb_before_browser_(browser, frame, request, is_redirect);
//
//	return result;
//}
//
//void CefControlBase::OnProtocolExecution(CefRefPtr<CefBrowser> browser, const CefString& url, bool& allow_os_execution)
//{
//	if (cb_protocol_execution_)
//		cb_protocol_execution_(browser, url, allow_os_execution);
//}
//
//CefRequestHandler::ReturnValue CefControlBase::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefRequestCallback> callback)
//{
//	if (cb_before_resource_load_)
//		return cb_before_resource_load_(request, false);
//
//	return RV_CONTINUE;
//}
//
//void CefControlBase::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser, CefRequestHandler::TerminationStatus status)
//{
//	return;
//}
//
//void CefControlBase::OnBeforeDownload(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item, const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback)
//{
//	if (cb_before_download_)
//		cb_before_download_(browser, download_item, suggested_name, callback);
//}
//
//void CefControlBase::OnDownloadUpdated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item, CefRefPtr<CefDownloadItemCallback> callback)
//{
//	if (cb_download_updated_)
//		cb_download_updated_(browser, download_item, callback);
//}
//
//bool CefControlBase::OnFileDialog(CefRefPtr<CefBrowser> browser, CefDialogHandler::FileDialogMode mode, const CefString& title, const CefString& default_file_path, const std::vector<CefString>& accept_filters, int selected_accept_filter, CefRefPtr<CefFileDialogCallback> callback)
//{
//	if (cb_file_dialog_)
//		return cb_file_dialog_(mode, title, default_file_path, accept_filters, selected_accept_filter, callback);
//	else
//		return false;
//}

bool CefControlBase::OnExecuteCppFunc(const CefString& function_name, const CefString& params, int js_callback_id, CefRefPtr<CefBrowser> browser)
{
	if (js_bridge_.get())
	{
		js_callback_thread_id_ = nbase::FrameworkThread::GetManagedThreadId();
		return js_bridge_->ExecuteCppFunc(function_name, params, js_callback_id, browser);
	}

	return false;
}

bool CefControlBase::OnExecuteCppCallbackFunc(int cpp_callback_id, const CefString& json_string)
{
	if (js_bridge_.get())
	{
		if (js_callback_thread_id_ != -1)
		{
			nbase::ThreadManager::PostTask(js_callback_thread_id_, [this, cpp_callback_id, json_string]
			{
				js_bridge_->ExecuteCppCallbackFunc(cpp_callback_id, json_string);
			});
		}
		else
		{
			return js_bridge_->ExecuteCppCallbackFunc(cpp_callback_id, json_string);
		}

	}

	return false;
}

}